package com.meida.module.bus.provider.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.meida.common.base.entity.EntityMap;
import com.meida.common.base.utils.FlymeUtils;
import com.meida.common.constants.CommonConstants;
import com.meida.common.enums.OnLineEnum;
import com.meida.common.mybatis.base.service.impl.BaseServiceImpl;
import com.meida.common.mybatis.model.ResultBody;
import com.meida.common.mybatis.query.CriteriaDelete;
import com.meida.common.mybatis.query.CriteriaQuery;
import com.meida.common.mybatis.query.CriteriaSave;
import com.meida.common.mybatis.query.CriteriaUpdate;
import com.meida.common.security.OpenHelper;
import com.meida.common.utils.ApiAssert;
import com.meida.common.utils.DateUtils;
import com.meida.module.bus.provider.service.BusProductService;
import com.meida.module.bus.provider.util.ConvertUtil;
import com.meida.module.file.client.entity.SysFile;
import com.meida.module.file.provider.service.SysFileService;
import com.meida.module.product.client.entity.ProdProduct;
import com.meida.module.product.client.entity.ProdProductdetails;
import com.meida.module.product.provider.mapper.ProdProductMapper;
import com.meida.module.product.provider.service.ProdProductdetailsService;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 产品接口实现类
 *
 * @author flyme
 * @date 2022-06-22
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class BusProductServiceImpl extends BaseServiceImpl<ProdProductMapper, ProdProduct> implements BusProductService {


    @Autowired
    private ProdProductdetailsService productdetailsService;

    @Resource
    private SysFileService fileService;

    @Override
    @Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
    public ResultBody beforeListEntityMap(CriteriaQuery<ProdProduct> cq, ProdProduct prodProduct, EntityMap requestMap) {
        cq.select(ProdProduct.class, "productId", "productName", "productNo", "productPrice", "onLineState", "auditState", "recommend", "coverImage", "deliveryTime", "oldPrice", "saleCount");
        return super.beforeListEntityMap(cq, prodProduct, requestMap);
    }

    @Override
    @Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
    public ResultBody beforePageList(CriteriaQuery<ProdProduct> cq, ProdProduct prodProduct, EntityMap requestMap) {
        //排序字段
        String order = requestMap.get("order", "createTime");
        //排序方式
        String sort = requestMap.get("sort", "desc");
        cq.select(ProdProduct.class, "productId", "productName", "productNo", "productPrice", "productSeries", "productScore", "oldPrice", "saleCount", "onLineState", "auditState", "recommend", "createTime", "updateTime", "coverImage", "deliveryTime", "categoryName");
        cq.likeByField(ProdProduct.class, "productSeries");
        cq.likeByField(ProdProduct.class, "productNo");
        cq.likeByField(ProdProduct.class, "productName");
        cq.eq(ProdProduct.class, "onLineState");
        cq.ge(ObjectUtil.isNotEmpty(requestMap.get("beginDate")), "createTime", requestMap.get("beginDate"));
        cq.le(ObjectUtil.isNotEmpty(requestMap.get("endDate")), "createTime", requestMap.get("endDate"));

        //cq.between() //AND DATE_FORMAT(user.createTime, '%Y-%m-%d') >= '2022-06-01' AND DATE_FORMAT(user.createTime, '%Y-%m-%d') <= '2022-06-03'
        cq.orderBy(order, sort);
        return ResultBody.ok();
    }

    @Override
    @Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
    public ResultBody beforeAdd(CriteriaSave cs, ProdProduct product, EntityMap extra) {
        product.setDeleted(CommonConstants.DEL_NO);
        product.setCompanyId(OpenHelper.getCompanyId());
        return ResultBody.ok();
    }

    @Override
    @Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
    public ResultBody afterAdd(CriteriaSave cs, ProdProduct save, EntityMap extra) {
        Long productId = save.getProductId();
        String allSpec = cs.getParams("allSpec");
        String privateSpec = cs.getParams("privateSpec");
        String packinglist = cs.getParams("packinglist");
        String remark = cs.getParams("remark");
        String productDesc = cs.getParams("productDesc");
        String productVideo = cs.getParams("productVideo");
        String afterService = cs.getParams("afterService");
        ProdProductdetails details = new ProdProductdetails();
        details.setAllSpec(allSpec);
        details.setPackinglist(packinglist);
        details.setProductVideo(productVideo);
        details.setPrivateSpec(privateSpec);
        details.setAfterService(afterService);
        details.setProductDesc(productDesc);
        details.setRemark(remark);
        details.setProductDetailsId(productId);
        productdetailsService.save(details);

        return ResultBody.ok("添加成功");
    }

    @Override
    @Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
    public ResultBody afterEdit(CriteriaUpdate cs, ProdProduct up, EntityMap extra) {
        Long productId = up.getProductId();
        String remark = cs.getParams("remark")+"";
        String productDesc = cs.getParams("productDesc").toString();
        String productImage = cs.getParams("productImage")+"";
        ProdProductdetails details = new ProdProductdetails();
        details.setProductDesc(productDesc);
        details.setProductImage(productImage);
        details.setRemark(remark);
        details.setProductDetailsId(productId);
        productdetailsService.updateById(details);
        return ResultBody.ok("编辑成功");
    }
    //@Override
    //@Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
    //public ResultBody beforeDelete(CriteriaDelete<ProdProduct> cd) {
    //    Long[] ids = cd.getIds();
    //    Integer count = (Integer) amqpTemplate.convertSendAndReceive(QueueConstants.QUEUE_ORDER_CHECK, ids);
    //    cd.setCount(count);
    //    return super.beforeDelete(cd);
    //}

    @Override
    @Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
    public ResultBody afterDelete(CriteriaDelete cd, Long[] ids) {
        productdetailsService.removeByIds(Arrays.asList(ids));
        return super.afterDelete(cd, ids);
    }


    @Override
    public void afterGet(CriteriaQuery cq, EntityMap result) {
        Long productId = result.getLong("productId");
        String videoUrl = "";
        ProdProductdetails details = productdetailsService.getById(productId);
        if (FlymeUtils.isNotEmpty(details)) {
            //商品详情
            result.put("productDesc", details.getProductDesc());
            result.put("allSpec", details.getAllSpec());
            result.put("productImage", details.getProductImage());
            result.put("productVideo", details.getProductVideo());
            result.put("remark", details.getRemark());
        }

        //产品图片轮播图
        List<EntityMap> sliderImageList = fileService.selectFileListByFileType(productId, ProdProduct.class, "image");
        result.put("sliderImageList", sliderImageList);

    }

    @Override
    public Object listForIndex() {
        //CriteriaQuery<Product> cq=new CriteriaQuery<>(Product.class);
        //cq.eq(true, "product.deleted", CommonConstants.DEL_NO);
        //cq.eq(true, "product.onLineState", CommonConstants.ENABLED);
        //cq.orderByDesc("product.createTime");
        QueryWrapper<ProdProduct> wrapper = new QueryWrapper<>();
        wrapper.eq(true, "deleted", CommonConstants.DEL_NO);
        wrapper.eq(true, "onLineState", CommonConstants.ENABLED);
        wrapper.orderByDesc(StrUtil.split("recommend,createTime", ','));
        return this.list(wrapper);
    }

    @Override
    public ResultBody setonLineState(Long[] productIds, Integer onlineState) {
        ApiAssert.isNotEmpty("主键不能为空", productIds);
        UpdateWrapper product = new UpdateWrapper();
        product.set("onLineState", onlineState);
        product.set("onlineDate", DateUtils.getDateTime());
        product.in("productId", productIds);
        boolean result = update(product);
        if (result) {
            return ResultBody.ok(OnLineEnum.getValue(onlineState) + "成功", onlineState);
        } else {
            return ResultBody.failed(OnLineEnum.getValue(onlineState) + "失败");
        }
    }

    @SneakyThrows
    @Override
    public Object getProductDetail(Long productId) {
        ProdProduct product = getById(productId);
        Map<String, Object> map = ConvertUtil.objectToMap(product);
        ProdProductdetails details = productdetailsService.getById(productId);
        if (FlymeUtils.isNotEmpty(details)) {
            //商品详情
            Map<String, Object> detail = ConvertUtil.objectToMap(details);
            map.putAll(detail);
        }
        //产品图片轮播图
        List<EntityMap> sliderImageList = fileService.selectFileListByFileType(productId, ProdProduct.class, "image");
        map.put("sliderImageList", sliderImageList);
        return map;
    }

    @Override
    public void updateSaleCount(Long productId, Integer saleCount) {
        this.update(new UpdateWrapper<ProdProduct>().lambda().eq(ProdProduct::getProductId, productId).set(ProdProduct::getSaleCount, saleCount));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultBody setRecommend(Long[] ids, Integer recommend) {
        Map<String, Object> map = new HashMap<>();
        map.put("ids", ids);
        CriteriaUpdate cq = new CriteriaUpdate(map, entityClass);
        ApiAssert.isNotEmpty("主键不能为空", ids);
        String idField = cq.getIdField();
        UpdateWrapper uw = new UpdateWrapper();
        uw.set("recommend", recommend);
        uw.in(idField, ids);
        boolean result = update(uw);
        return ResultBody.result(result, recommend);
    }


}
